﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using OpenExpressApp.MetaAttribute;
using System.Reflection;
using System.Collections;
using OpenExpressApp.Command;
using OpenExpressApp.Types;
using System.Diagnostics;
using OpenExpressApp.MetaModel;
using System.Windows.Media;
using Csla;
using OpenExpressApp.MetaModel.Utils;

namespace OpenExpressApp
{
    /// <summary>
    /// 业务对象的属性元数据
    /// 
    /// EntityPropertyAttribute
    /// </summary>
    [Serializable]
    [BusinessObject("F1461096-A382-4A8A-BB0C-18AEFE240A6B"), Label("对象属性")]
    public class BusinessObjectPropertyInfo : IEntityPropertyInfo, IEntityPropertyViewInfo
    {
        private string _label;

        /// <summary>
        /// 解析元数据
        /// </summary>
        /// <param name="propertyInfo">对应的属性</param>
        /// <param name="boInfo">属性所属的类型元数据</param>
        public BusinessObjectPropertyInfo(PropertyInfo runtimeProperty, BusinessObjectInfo boInfo)
        {
            this.EntityPropertyAttribute = runtimeProperty.GetSingleAttribute<EntityPropertyAttribute>();
            this.IsReadOnlyAttribute = runtimeProperty.GetSingleAttribute<IsReadOnlyAttribute>();
            this.BoInfo = boInfo;
            this.RuntimeProperty = runtimeProperty;
            this.IsTitle = runtimeProperty.HasMarked<IsTitleAttribute>();
            this.Required = runtimeProperty.HasMarked<RequiredAttribute>();

            this.ShowInList = runtimeProperty.HasMarked<ShowInListAttribute>();
            this.ShowInDetail = runtimeProperty.HasMarked<ShowInDetailAttribute>();
            this.ShowInLookup = runtimeProperty.HasMarked<ShowInLookupAttribute>() ||
                (this.IsTitle && runtimeProperty.HasMarked<NotShowInLookupAttribute>() == false);
            if (this.ShowInList)
            {
                this.MinWidth = runtimeProperty.GetSingleAttribute<ShowInListAttribute>().MinWidth;
            }
            this.Name = runtimeProperty.Name;

            if (runtimeProperty.HasMarked<LabelAttribute>())
            {
                this.Label = runtimeProperty.GetSingleAttribute<LabelAttribute>().Label;
            }
            this.NotCopy = runtimeProperty.HasMarked<NotCopyAttribute>();

            this.IsNavigateQueryItem = runtimeProperty.HasMarked<NavigateQueryItemAttribute>();
            if (runtimeProperty.HasMarked<QueryItemValueTypeAttribute>())
            {
                this.QueryItemValueTypeAttribute = runtimeProperty.GetSingleAttribute<QueryItemValueTypeAttribute>();
            }

            this.PropertyType = runtimeProperty.PropertyType;

            if (runtimeProperty.HasMarked<LookupAttribute>())
            {
                this.LookupAttribute = runtimeProperty.GetSingleAttribute<LookupAttribute>();
                string lookupPropertyName = this.LookupAttribute.LookupPropertyName;
                if (string.IsNullOrEmpty(lookupPropertyName) == false)
                {
                    PropertyInfo lookupInfo = runtimeProperty.ReflectedType.GetProperty(lookupPropertyName);
                    Debug.Assert(null != lookupInfo, "类型" + runtimeProperty.ReflectedType.ToString() + "不存在Lookup属性" + lookupPropertyName);
                    this.LookupAttribute.LookupType = lookupInfo.PropertyType;
                }
            }

            if (runtimeProperty.HasMarked<EditorAttribute>())
            {
                this.EditorName = runtimeProperty.GetSingleAttribute<EditorAttribute>().Name;
            }
            else
            {
                if (this.IsLookup)
                {
                    this.EditorName = EditorNames.LookupDropDown;
                }
                else
                {
                    this.EditorName = PropertyType.MapToEditor();
                }
            }
            if (runtimeProperty.HasMarked<IsVisibleAttribute>())
            {
                this.IsVisibleAttribute = runtimeProperty.GetSingleAttribute<IsVisibleAttribute>();
            }
        }

        /// <summary>
        /// 是否可见属性
        /// </summary>
        public IsVisibleAttribute IsVisibleAttribute { get; private set; }
        /// <summary>
        /// 对应的属性
        /// </summary>
        public PropertyInfo RuntimeProperty { get; private set; }
        /// <summary>
        /// 是否是必须的
        /// RequiredAttribute
        /// </summary>
        public bool Required { get; private set; }
        /// <summary>
        /// 是否显示在列表中
        /// ShowInListAttribute
        /// </summary>
        public bool ShowInList { get; private set; }
        /// <summary>
        /// 是否显示在Lookup列表中
        /// ShowInLookup
        /// </summary>
        public bool ShowInLookup { get; private set; }
        /// <summary>
        /// 是否显示在详细界面中
        /// ShowInDetailAttribute
        /// </summary>
        public bool ShowInDetail { get; private set; }
        /// <summary>
        /// 是否标记了NotCotyAttribute
        /// </summary>
        public bool NotCopy { get; private set; }
        /// <summary>
        /// 查询面板列表类型(ListView)编辑器返回的查询参数值类型
        /// 
        /// 从标记的QueryItemValueTypeAttribute中读取
        /// </summary>
        public QueryItemValueTypeAttribute QueryItemValueTypeAttribute { get; private set; }
        /// <summary>
        /// 标题
        /// 如果是Lookup属性，则显示Lookup对应的类型的标题。
        /// 否则显示属性名
        /// </summary>
        public string Label
        {
            get
            {
                string l = this._label;
                if (l == null)
                {
                    //获取关联对象的名称
                    if (this.IsLookup)
                    {
                        l = ApplicationModel.GetBusinessObjectInfo(LookupAttribute.LookupType).Label;
                    }
                    else
                    {
                        l = RuntimeProperty.Name;
                    }
                }
                return l;
            }
            set
            {
                this._label = value;
            }
        }
        /// <summary>
        /// 格式化String
        /// </summary>
        public string StringFormat
        {
            get
            {
                var value = this.EntityPropertyAttribute.StringFormat;

                //数字的默认显示方式
                if (string.IsNullOrEmpty(value) &&
                    TypeHelper.IsNumber(this.RuntimeProperty.PropertyType)
                    )
                {

                    value = "{0:N}";
                }

                return value;
            }
        }
        /// <summary>
        /// 如果标记了ShowInList
        /// 则可以设置显示时的最小宽度
        /// </summary>
        public double MinWidth { get; private set; }
        /// <summary>
        /// 属性名
        /// </summary>
        public string Name { get; private set; }
        /// <summary>
        /// 属性类型
        /// </summary>
        public Type PropertyType { get; private set; }
        /// <summary>
        /// 编辑器名
        /// EditorAttribute中标记
        /// </summary>
        public string EditorName { get; private set; }
        /// <summary>
        /// 是否标记了LookupAttribute
        /// </summary>
        public bool IsLookup
        {
            get { return null != LookupAttribute; }
        }
        /// <summary>
        /// 是否标记了NavigateQueryItemAttribute
        /// </summary>
        public bool IsNavigateQueryItem { get; private set; }
        /// <summary>
        /// 是否显示为这个类型的标题
        /// IsTitleAttribute
        /// </summary>
        public bool IsTitle { get; private set; }
        /// <summary>
        /// 标记的LookupAttribute
        /// </summary>
        public LookupAttribute LookupAttribute { get; private set; }
        /// <summary>
        /// 所在类型的元数据
        /// </summary>
        public BusinessObjectInfo BoInfo { get; private set; }
        /// <summary>
        /// 标记的ReadOnlyAttribute
        /// </summary>
        public IsReadOnlyAttribute IsReadOnlyAttribute { get; private set; }
        /// <summary>
        /// 标记的EntityPropertyAttribute
        /// </summary>
        private EntityPropertyAttribute EntityPropertyAttribute { get; set; }
        /// <summary>
        /// 排序此属性使用的属性。
        /// </summary>
        public double OrderNo
        {
            get
            {
                return this.EntityPropertyAttribute.OrderNo;
            }
        }

        public override string ToString()
        {
            return this.BoInfo.Name + ":" + this.Name + ":" + base.ToString();
        }

        #region IEntityPropertyInfo Members

        IEntityInfo IPropertyInfo.EntityInfo
        {
            get
            {
                return this.BoInfo;
            }
        }

        #endregion

        #region IEntityPropertyViewInfo Members

        public IEntityPropertyInfo PropertyInfo
        {
            get { return this; }
        }

        IPropertyInfo IPropertyViewInfo.PropertyInfo
        {
            get
            {
                return this;
            }
        }

        #endregion
    }
}
